#include "Drv_IIC.h"
#include "gd32f1x0.h"
#include "macro.h"
#include <stdio.h>
#include "Drv_THSensor.h"
#include "Lib_Delay.h"
#include "global.h"

#define i2cAddWrite_8bit 0x88
#define i2cAddRead_8bit 0x89

/*CRC*/
#define POLYNOMIAL 0x131  // P(x) = x^8 + x^5 + x^4 + 1 = 100110001

/****************************************************************/
uint16_t Tem_Value = 0;
uint16_t RH_Value  = 0;

/************************* Inside io ****************************/

/******************************************************/
void SHT3X_WriteCMD(u16 cmd)
{
    I2C_Start();
    I2C_SendByte(i2cAddWrite_8bit);
    I2C_Wait_Ack();
    I2C_SendByte(cmd >> 8);
    I2C_Wait_Ack();
    I2C_SendByte(cmd);
    I2C_Wait_Ack();
    I2C_Stop();
    osDelay(10);
    //Delay_ms(10);
}

/********************************************************/
void SHT3X_SetPeriodicMeasurement()
{
    //    SHT3X_WriteCMD(CMD_MEAS_PERI_2_H);
    SHT3X_WriteCMD(CMD_MEAS_PERI_1_H);
}

//在AT24CXX指定地址读出一个数据
// ReadAddr:开始读数的地址
//返回值  :读到的数据
// u8 AT24CXX_ReadOneByte(void)
//{
//	u8 temp=0;
//    I2C_Start();
//    I2C_SendByte(0x44);   //发送器件地址0XA0,写数据
//	  I2C_Wait_Ack();
//    temp=I2C_ReciveByte(0);
//    I2C_Stop();//产生一个停止条件
//	return temp;
//}

void SHT3X_ReadState(u8 *temp)
{
    I2C_Start();
    I2C_SendByte(i2cAddWrite_8bit);
    I2C_Wait_Ack();
    I2C_SendByte(0xf3);
    I2C_Wait_Ack();
    I2C_SendByte(0X2d);
    I2C_Wait_Ack();
    I2C_Stop();
    Delay_ms(100);
    I2C_Start();
    I2C_SendByte(i2cAddRead_8bit);
    I2C_Wait_Ack();

    temp[0] = IIC_Read_Byte(0);
    I2C_Ack();
    temp[1] = IIC_Read_Byte(0);
    I2C_Ack();
    temp[2] = IIC_Read_Byte(0);
    I2C_NAck();
    I2C_Stop();
}

void SHX3X_ReadResults(u16 cmd, u8 *p)
{
    I2C_Start();
    I2C_SendByte(0x88);
    I2C_Wait_Ack();
    I2C_SendByte(cmd >> 8);
    I2C_Wait_Ack();
    I2C_SendByte(cmd);
    I2C_Wait_Ack();
    I2C_Stop();

    Delay_ms(100);
    I2C_Start();
    I2C_SendByte(0x89);
    I2C_Wait_Ack();

    p[0] = IIC_Read_Byte(1);
    //	I2C_Ack();
    p[1] = IIC_Read_Byte(1);
    //	I2C_Ack();
    p[2] = IIC_Read_Byte(1);
    //	I2C_Ack();
    p[3] = IIC_Read_Byte(1);
    //	I2C_Ack();
    p[4] = IIC_Read_Byte(1);
    //	I2C_Ack();
    p[5] = IIC_Read_Byte(0);
    //	I2C_NAck();
    I2C_Stop();
    Delay_ms(100);
}

/********************************************************************************/
/********************************************************************************/

u8 SHT3X_CalcCrc(uint8_t *data, uint8_t nbrOfBytes)
{
    uint8_t bit;         // bit mask
    uint8_t crc = 0xFF;  // calculated checksum
    uint8_t byteCtr;     // byte counter

    // calculates 8-Bit checksum with given polynomial
    for (byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++)
    {
        crc ^= (data[byteCtr]);
        for (bit = 8; bit > 0; --bit)
        {
            if (crc & 0x80)
            {
                crc = (crc << 1) ^ POLYNOMIAL;
            }
            else
            {
                crc = (crc << 1);
            }
        }
    }
    return crc;
}

u8 SHT3X_CheckCrc(uint8_t *pdata, uint8_t nbrOfBytes, uint8_t checksum)
{
    uint8_t crc;
    crc = SHT3X_CalcCrc(pdata, nbrOfBytes);  // calculates 8-Bit checksum
    if (crc == checksum)
    {
        return 1;
    }
    return 0;
}

int16_t SHT30_Read_T_H(void)
{
    u8 u8Result[6];
    INT16 i16TempRh = ERR_VALUE;
    uint32_t u32Temp, u32Hum;

    //    SHX3X_ReadResults(CMD_MEAS_CLOCKSTR_H, u8Result);CMD_FETCH_DATA

   // ENTER_CRITICAL_SECTION();  //关全局中断
    SHX3X_ReadResults(CMD_FETCH_DATA, u8Result);
   // EXIT_CRITICAL_SECTION();  //开中断
    // TEST
    g_sVariable.sTemperatureHumidity_inst.u16Buff[0] = u8Result[0];
    g_sVariable.sTemperatureHumidity_inst.u16Buff[1] = u8Result[1];
    g_sVariable.sTemperatureHumidity_inst.u16Buff[2] = u8Result[2];
    g_sVariable.sTemperatureHumidity_inst.u16Buff[3] = u8Result[3];
    g_sVariable.sTemperatureHumidity_inst.u16Buff[4] = u8Result[4];
    g_sVariable.sTemperatureHumidity_inst.u16Buff[5] = u8Result[5];
    /* check tem */
    if ((SHT3X_CheckCrc((u8 *)&u8Result, 2, u8Result[2])) &&
        (SHT3X_CheckCrc((u8 *)&u8Result[3], 2, u8Result[5])))  // CRC校验
    {
        i16TempRh = 0;
        u32Temp   = (u8Result[0] << 8) | u8Result[1];  //温度拼接
        u32Hum    = (u8Result[3] << 8) | u8Result[4];  //湿度拼接

        u32Temp = ((21875 * u32Temp) >> 13) - 45000;  //温度计算
        u32Hum  = ((12500 * u32Hum) >> 13);           //湿度计算

        Tem_Value = u32Temp / 100;
        RH_Value  = u32Hum / 100;
    }
    else
    {
        Tem_Value = DFT_TEMP;
        RH_Value  = DFT_HUM;
    }
    //限值
    if (Tem_Value >= MAX_VALUE)
    {
        Tem_Value = MAX_VALUE;
    }
    if (RH_Value >= MAX_VALUE)
    {
        RH_Value = MAX_VALUE;
    }

    return i16TempRh;
}

void SHT_Init(void)
{
    Delay_ms(100); /* Must add delay */
    SHT3X_SetPeriodicMeasurement();
    Delay_ms(100); /* Must add delay */
}

void HTU21D_Init(void)
{
    I2C_Start();                     //启动I2C
    I2C_SendByte(HTU21ADDR & 0xFE);  //?HTU21I2C??
    I2C_ReciveByte();
    I2C_Stop();      //停止I2C
    I2C_Delay(600);  //延时
}

/*************************************************
  Function:       // TransducerInit
  Description:    // Transducer初始化函数
  Calls:          // IIC_Init()
                                          I2C_Start()
                                          I2C_SendByte()
                                          I2C_ReciveByte()
                                          I2C_Stop()
                                          I2C_Delay()
  Called By:      // TemperatureHumidity_Proc
  Table Accessed: // None
  Table Updated:  // None
  Input:          // None
  Output:         // None
  Return:         // None
  Others:         // None
*************************************************/
void TransducerInit(void)
{
    IIC_Init();  // I2C初始化
#if SHT30
    SHT_Init();
#else
    HTU21D_Init();
#endif
}
